#!/bin/bash

# Nexus 仓库完整备份工具
# 功能：从Nexus3下载指定仓库的所有文件并保留目录结构
# 支持配置：仓库地址、用户名、密码、仓库名称、本地保存路径

# 默认配置
NEXUS_URL="http://public.repo.ddns.e-lead.cn:8081"                      # Nexus仓库地址
NEXUS_USERNAME="developer"                 # Nexus用户名
NEXUS_PASSWORD="elead@2018"                 # Nexus密码
LOCAL_PATH="./downloaded_jars"    # 本地保存路径
REPOSITORY_NAME="elead-erdc-ga"                # 要下载的仓库名称

# 日志函数
echo_info() {
    echo "[INFO] $1"
}

echo_error() {
    echo "[ERROR] $1" >&2
}

# 显示帮助信息
show_help() {
    echo "使用方法: $0 [选项]"
    echo ""
    echo "选项:" 
    echo "  -u, --url <url>          Nexus仓库地址 (必填)"
    echo "  -n, --username <name>    Nexus用户名 (必填)"
    echo "  -p, --password <pwd>     Nexus密码 (必填)"
    echo "  -r, --repository <repo>  要下载的仓库名称 (必填)"
    echo "  -l, --local <path>       本地保存路径 (默认: ./downloaded_jars)"
    echo "  -h, --help               显示帮助信息"
    echo ""
    echo "示例:"
    echo "  $0 --url http://nexus.example.com --username admin --password admin123 --repository maven-releases --local ./jars"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -u|--url) 
            NEXUS_URL="$2"
            shift 2
            ;;
        -n|--username) 
            NEXUS_USERNAME="$2"
            shift 2
            ;;
        -p|--password) 
            NEXUS_PASSWORD="$2"
            shift 2
            ;;
        -r|--repository) 
            REPOSITORY_NAME="$2"
            shift 2
            ;;
        -l|--local) 
            LOCAL_PATH="$2"
            shift 2
            ;;
        -h|--help) 
            show_help
            exit 0
            ;;
        *) 
            echo_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
done

# 检查必要参数
check_required_params() {
    local missing_params=""
    
    if [[ -z "$NEXUS_URL" ]]; then
        missing_params="$missing_params --url"
    fi
    
    if [[ -z "$NEXUS_USERNAME" ]]; then
        missing_params="$missing_params --username"
    fi
    
    if [[ -z "$NEXUS_PASSWORD" ]]; then
        missing_params="$missing_params --password"
    fi
    
    if [[ -z "$REPOSITORY_NAME" ]]; then
        missing_params="$missing_params --repository"
    fi
    
    if [[ -n "$missing_params" ]]; then
        echo_error "缺少必要参数:$missing_params"
        show_help
        exit 1
    fi
}

# 检查wget或curl是否可用
detect_download_tool() {
    if command -v wget &> /dev/null; then
        DOWNLOAD_TOOL="wget"
    elif command -v curl &> /dev/null; then
        DOWNLOAD_TOOL="curl"
    else
        echo_error "未找到wget或curl，请安装其中一个工具。"
        exit 1
    fi
    echo_info "使用 $DOWNLOAD_TOOL 作为下载工具"
}

# 创建本地保存目录
create_local_directory() {
    if [[ ! -d "$LOCAL_PATH" ]]; then
        echo_info "创建本地保存目录: $LOCAL_PATH"
        mkdir -p "$LOCAL_PATH"
        if [[ $? -ne 0 ]]; then
            echo_error "创建目录失败: $LOCAL_PATH"
            exit 1
        fi
    fi
}

# 获取仓库中的所有文件信息（支持分页获取）
fetch_artifacts_list() {
    # 不限制格式，获取仓库中的所有文件
    local nexus_api_url="${NEXUS_URL}/service/rest/v1/search/assets?repository=${REPOSITORY_NAME}&sort=name"
    local temp_file="${LOCAL_PATH}/artifacts_list.json"
    
    echo_info "正在获取仓库 ${REPOSITORY_NAME} 中的所有文件列表..."
    echo_info "这个过程可能需要一些时间，请耐心等待..."
    echo_info "temp_file: $temp_file"
    
    if [[ "$DOWNLOAD_TOOL" == "wget" ]]; then
        wget --user="$NEXUS_USERNAME" --password="$NEXUS_PASSWORD" --no-check-certificate -O "$temp_file" "$nexus_api_url"
    else
        curl -u "$NEXUS_USERNAME:$NEXUS_PASSWORD" -k -o "$temp_file" "$nexus_api_url"
    fi
    
    if [[ $? -ne 0 ]]; then
        echo_error "获取jar包列表失败，请检查Nexus地址、用户名、密码和仓库名称是否正确。"
        exit 1
    fi
    
    # 检查是否有文件
    local artifacts_count=$(grep -o '"downloadUrl":' "$temp_file" | wc -l)
    if [[ $artifacts_count -eq 0 ]]; then
        echo_info "在仓库 ${REPOSITORY_NAME} 中未找到jar包和pom.xml文件。"
        # rm -f "$temp_file"
        exit 0
    fi
    
    echo_info "找到 $artifacts_count 个文件需要下载。"
    echo "$temp_file"
}

# 下载所有文件并保留目录结构
download_artifacts() {
    local artifacts_list_file="$1"
    local total_downloaded=0
    local total_failed=0
    
    echo_info "开始下载所有文件到 ${LOCAL_PATH}，并保留原始目录结构..."
    echo_info "下载进度："
    
    # 提取downloadUrl并下载，同时保留目录结构
    grep -o '"downloadUrl":"[^"]*"' "$artifacts_list_file" | sed 's/"downloadUrl":"//' | sed 's/"$//' | while read -r download_url; do
        # 从URL中提取文件路径（相对于仓库的路径）
        # 示例URL: http://nexus.example.com/repository/repo-name/group/path/artifact.jar
        local repo_url_base="${NEXUS_URL}${REPOSITORY_NAME}/"
        local relative_path=${download_url#$repo_url_base}
        
        # 构建本地保存路径（保留目录结构）
        local local_file_path="${LOCAL_PATH}/${relative_path}"
        local local_dir_path=$(dirname "$local_file_path")
        local file_name=$(basename "$local_file_path")
        
        # 创建必要的目录结构
        if [[ ! -d "$local_dir_path" ]]; then
            mkdir -p "$local_dir_path"
        fi
        
        echo_info "正在下载: $relative_path"
        
        if [[ "$DOWNLOAD_TOOL" == "wget" ]]; then
            wget --user="$NEXUS_USERNAME" --password="$NEXUS_PASSWORD" --no-check-certificate -O "$local_file_path" "$download_url"
        else
            curl -u "${NEXUS_USERNAME}:${NEXUS_PASSWORD}" -k -o "$local_file_path" "$download_url"
        fi
        
        if [[ $? -eq 0 ]]; then
            total_downloaded=$((total_downloaded + 1))
            echo_info "下载成功: $jar_filename"
        else
            total_failed=$((total_failed + 1))
            echo_error "下载失败: $jar_filename"
        fi
    done
    
    echo_info "下载完成。成功: $total_downloaded, 失败: $total_failed"
    
    # 清理临时文件
    rm -f "$artifacts_list_file"
}

# 主函数
main() {
    check_required_params
    detect_download_tool
    create_local_directory
    
    local artifacts_list_file=$(fetch_artifacts_list)
    download_artifacts "$artifacts_list_file"
    
    echo_info "所有操作已完成。"
}

# 执行主函数
main